const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');


module.exports = {
  // 入口文件
  entry: {
    // 指定从哪个文件开始打包,
    // 是相对于 context 配置的路径的, 默认是process.cwd()指当前执行node命令时候的文件夹地址, 与package.json同级
    main: './src/index.js',
  },
  resolve: {
    // 当引入文件时, 先去找.js结尾的文件, 然后再去找.jsx
    extensions: ['.js', '.jsx'],
    // 当直接引入文件夹时, 先去找index.js, 再去找test.js
    // mainFiles: ['index', 'test'],
    alias: {
      // 配置别名
      Css: path.resolve(__dirname, '../src/css/')
    }
  },
  // 模块(可以是图片, js文件, css文件等), 每个文件引入的时候都是一个模块
  module: {
    rules: [
      // {
      //   // 识别所有以jpg结尾的模块
      //   test: /\.(png|jpe?g|gif)$/i,
      //   // 当打包到该类型的模块时, 使用file-loader将该类型的模块转化成有效的模块
      //   use: {
      //     // 底层逻辑是将图片类的模块移动到dist目录, 然后修改其名字, 再将该名字返回给变量
      //     loader: 'file-loader',
      //     options: {
      //       // 重命名输出文件
      //       name: '[name]_[hash].[ext]',
      //       // 指定输出文件的存放路径(相对于output -> path的dist文件夹)
      //       outputPath: 'images',
      //     }
      //   }
      // },
      {
        // 打包字体文件, 移到dist目录下
        test: /\.(ttf|eot|woff|woff2|svg)$/,
        use: {
          loader: 'file-loader'
        }
      },
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: {
          // url-loader拥有file-loader所有的功能, 当目标文件小于limit参数, 则以base64的形式直接打包到bundle里, 反之移动到输出文件夹(dist)下面
          loader: 'url-loader',
          options: {
            name: '[name]_[hash].[ext]',
            outputPath: 'images',
            limit: 5000
          }
        }
      }
    ]
  },
  // 出口文件
  output: {
    // 在dist的index.html中的引入文件加入前缀, 如配置cdn前缀 http://cdn.com.cn 或者 '/' 根路径
    // publicPath: '/',

    // 指定打包出的文件, 放到哪个文件夹下(需要绝对路径)
    // __dirname => /Users/zichong/blogs/myTest/webpack-demo/webpackConfig
    path: path.resolve(__dirname, '../dist'),
  },
  plugins: [
    // 在(打包之前), 默认清空output里面设置的文件夹里的所有内容
    new CleanWebpackPlugin(),
    // 在(打包结束后), 自动生成一个html文件, 并把打包生成的bundle.js文件自动引入到这个文件中
    new HtmlWebpackPlugin({
      template: './src/template/index.html'
    }),
    new webpack.ProvidePlugin({
      // 当代码中有使用到$时, 自动去import jquery
      $: 'jquery'
    }),
    // 将build出来的vendors.dll.js引入到由HtmlWebpackPlugin生成的index.html里
    new AddAssetHtmlWebpackPlugin({
      filepath: path.resolve(__dirname, '../dll/vendors.dll.js')
    }),
    // 当引入第三方模块的时候, 先去manifest.json里面找映射关系, 直接从vendor.dll.js里面全局变量([name]即vendors)拿, 如果找不到, 去nodemodule里面拿
    new webpack.DllReferencePlugin({
      manifest: path.resolve(__dirname, '../dll/vendors.manifest.json')
    })
  ],
  optimization: {
    // 配置Tree Shaking
    usedExports: true,
    // 业务逻辑和第三方包代码分割
    splitChunks: {
      chunks: 'all', // 同步import的代码生效, (aysnc / all / initial)
      minSize: 30000, // 引入的库至少(大于)是30000byte(30KB), 则进行代码分割,
      minChunks: 1, // 某库至少被打包出来的chunks引入过1次 (打包出来的每个js文件都属于chunk)
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/, // 检测是否从nodemodule里引入
          priority: -10, // 如果default 也设置了priority, 根据值越大的优先级越高
          name: 'vendors'
        },
        // 当符合同步代码分割, 又不符合cacheGroups.vendors的条件时, 会进入default
        default: false
      }
    }
  }
}